// Deep power down mode --Forbidding all operations and then releasing back and executing the commands.
`include "defines.sv"

class DeepPowerDownMode extends axi_lite_base_test;
    
  `uvm_component_utils(DeepPowerDownMode)
  
  //---------------------------------------
  // sequence instance 
  ////-------------------------------------
  
  axi_lite_write_seq wseq;
  axi_lite_read_seq rseq;

  //---------------------------------------
  // constructor
  //---------------------------------------
  function new(string name = "DeepPowerDownMode",uvm_component parent=null);
    super.new(name,parent);
  endfunction : new

  //---------------------------------------
  // build_phase
  //---------------------------------------
  virtual function void build_phase(uvm_phase phase);    
    super.build_phase(phase);

    // Create the sequence
    
    wseq = axi_lite_write_seq::type_id::create("wseq");
    rseq = axi_lite_read_seq::type_id::create("rseq");
		
  endfunction : build_phase
  
  //---------------------------------------
  // run_phase - starting the test
  //---------------------------------------
  task run_phase(uvm_phase phase);
    
    phase.raise_objection(this);    
	wseq.waddr      = 0; 
	wseq.wdata      = 32'h00000000;
	wseq.addrv_i    = 1'b0;
	wseq.datav_i    = 1'b0;
	
	#100000;
	//wseq.waddr      = 32'1; 
	//wseq.wdata      = 32'0;
	wseq.addrv_i    = 1'b1;
	wseq.datav_i    = 1'b1;
	    
	// sending address and data to QUADSPI_CR
	wseq.waddr   = `QUADSPI_CR; 
	wseq.wdata   = 32'h031f0f01; // Enable QSPI 25 MHz
    wseq.start(env.axi_agnt.sequencer);
	
    // sending data to QUADSPI_DCR
	wseq.waddr   = `QUADSPI_DCR; 
	wseq.wdata   = 32'h001b0001;  
    wseq.start(env.axi_agnt.sequencer);
         
    wait(axi_master_tb_top_qspi.flash_inst.flash.Chip_EN);
	
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	//wseq.wdata   = 32'h00003106;   
	wseq.wdata   = 32'h000001B9; // deep power down mode   
    wseq.start(env.axi_agnt.sequencer);
    
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);		
  
    //wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
	
	//10ms delay
			#4000000;
			
				// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003106;   
	//wseq.wdata   = 32'h00000106;  
    wseq.start(env.axi_agnt.sequencer);
    
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);		
  
    //wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
    // sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003521;  //  SectorErase 
	//wseq.wdata   = 32'h00003564;  //  SectorErase on SIR for 4 byte address 
    wseq.start(env.axi_agnt.sequencer);    
    
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR; 
	//wseq.wdata   = 32'h01000000; 
	wseq.wdata   = 32'h00010000;  
    wseq.start(env.axi_agnt.sequencer);
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);
	   
    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
		    		    
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h000001AB;  //Release power down mode
    wseq.start(env.axi_agnt.sequencer); 	
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
		  
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);		

    //wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
			#2000000000;
		    #2000000000;
		    #2000000000;
		    #2000000000;
		    #2000000000;
	
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003106;   
	//wseq.wdata   = 32'h00000106;    
    wseq.start(env.axi_agnt.sequencer);
    
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);		
  
    //wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
    // sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003521;  //  SectorErase 
	//wseq.wdata   = 32'h00003564;  //  SectorErase on SIR for 4 byte address 
    wseq.start(env.axi_agnt.sequencer);    
    
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR; 
	//wseq.wdata   = 32'h01000000; 
	wseq.wdata   = 32'h00010000;  
    wseq.start(env.axi_agnt.sequencer);
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);
	   
    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
    
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003106;   
	//wseq.wdata   = 32'h00000106;   
    wseq.start(env.axi_agnt.sequencer);

	wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	   	
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);

    //wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP)); 
	    
	// sending data to QUADSPI_DLR
	wseq.waddr    = `QUADSPI_DLR; 
	wseq.wdata    = 32'h0000000F; // 16 bytes 
    wseq.start(env.axi_agnt.sequencer);		
		
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h01003512;  //  Data single Mode ,instruction & Address mode single
	//wseq.wdata = 32'h02003912;  //  Data Dual Mode ,instruction single & Address mode dual
	//wseq.wdata = 32'h01003562;  //  page program write, 4 byte address and instruction on single line
 
    wseq.start(env.axi_agnt.sequencer);			
	   
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR;
	wseq.wdata   = 32'h00010000; 
    wseq.start(env.axi_agnt.sequencer);		
	    
	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	//wseq.wdata   = 32'hff660000;  // 2 bytes data 
    wseq.wdata   = 32'h1234ff00;  //   
    wseq.start(env.axi_agnt.sequencer);	

	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff005678;  //   
    wseq.start(env.axi_agnt.sequencer);
	   
	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff124500;  //  
    wseq.start(env.axi_agnt.sequencer);
    
    // sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff981200;  //   
    wseq.start(env.axi_agnt.sequencer);	
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
		  
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);	

    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
	
	
//***************************************************************************************

//if read doesn't happen then we will confirmed the steps are under power down mode.  
    
	

	//wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
	   		
	// sending data to QUADSPI_DLR
	  wseq.waddr   = `QUADSPI_DLR; 
	  wseq.wdata   = 32'h0000000F;    //16 bytes
	//wseq.wdata   = 32'h0000000b;  //12 bytes 
	//wseq.wdata   = 32'h0000001F;  //32 bytes 
	//wseq.wdata   = 32'h00000010; 
 
    wseq.start(env.axi_agnt.sequencer);	

	//sending data to QUADSPI_CCR
	wseq.waddr = `QUADSPI_CCR; 
	wseq.wdata = 32'h05003513; // Normal read operation - 
	//wseq.wdata = 32'h05203513; // Normal read operation - 8 dummy cycles
	//wseq.wdata = 32'h05202568; // Normal read operation - 8 dummy cycles 
    wseq.start(env.axi_agnt.sequencer);	
	     
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR;
	//wseq.wdata = 32'h01000000;  //  
	//wseq.wdata = 32'h01000000;  //  
	wseq.wdata   = 32'h00010000; 
    wseq.start(env.axi_agnt.sequencer);			
    
	repeat (4) begin
    #10000000;	
    // Reading data from QUADSPI_DR
	rseq.raddr = `QUADSPI_DR;
    rseq.start(env.axi_agnt.sequencer);  
    end
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	    		
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer);














//***************************************************************	
	/* 
    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));	
	
    // sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h000001AB;  //Release power down mode

    wseq.start(env.axi_agnt.sequencer); 	
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
		  
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; 
 
    wseq.start(env.axi_agnt.sequencer);	

    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
	
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	//wseq.wdata   = 32'h00003106;   
	wseq.wdata   = 32'h00000106;   
 
    wseq.start(env.axi_agnt.sequencer);
    
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; 
 
    wseq.start(env.axi_agnt.sequencer);		
  
    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
    // sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	//wseq.wdata   = 32'h00003521;  //  SectorErase 
	wseq.wdata   = 32'h00003564;  //  SectorErase on SIR for 4 byte address
 
    wseq.start(env.axi_agnt.sequencer);    
    
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR; 
	//wseq.wdata   = 32'h01000000; 
	wseq.wdata   = 32'h00010000; 
 
    wseq.start(env.axi_agnt.sequencer);
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	
    // sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; 
 
    wseq.start(env.axi_agnt.sequencer);
	   
    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
    
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	//wseq.wdata   = 32'h00003106;   
	wseq.wdata   = 32'h00000106;   
 
    wseq.start(env.axi_agnt.sequencer);

	wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
	   	
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; 
 
    wseq.start(env.axi_agnt.sequencer);

    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP)); 
	    
	// sending data to QUADSPI_DLR
	wseq.waddr    = `QUADSPI_DLR; 
	wseq.wdata  =  32'h0000000F; 
 
    wseq.start(env.axi_agnt.sequencer);		
		
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	//wseq.wdata   = 32'h02003512;  //  Data Dual Mode ,instruction & Address mode single
	//wseq.wdata = 32'h02003912;  //  Data Dual Mode ,instruction single & Address mode dual
	wseq.wdata = 32'h01003562;  //  page program write, 4 byte address and instruction on single line
 
    wseq.start(env.axi_agnt.sequencer);			
	   
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR;
	wseq.wdata   = 32'h00010000;
 
    wseq.start(env.axi_agnt.sequencer);		
	    
	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	//wseq.wdata   = 32'hff660000;  // 2 bytes data 
    wseq.wdata   = 32'h1234ff00;  //  
 
    wseq.start(env.axi_agnt.sequencer);	

	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'h5678ff00;  //  
 
    wseq.start(env.axi_agnt.sequencer);
	   
	// sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'h4321ff00;  //  
 
    wseq.start(env.axi_agnt.sequencer);
    
    // sending data to QUADSPI_DR
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'h8765ff00;  //  
 
    wseq.start(env.axi_agnt.sequencer);	
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf);
		  
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; 
 
    wseq.start(env.axi_agnt.sequencer);	

    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));	
	
 //###############################################################   
	
	//if read happen then we will confirmed power down is released	  
    
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR; 
	//wseq.wdata   = 32'h01000000; 
	wseq.wdata   = 32'h00010000; 
 
    wseq.start(env.axi_agnt.sequencer);

	wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP));
	   		
	// sending data to QUADSPI_DLR
	  wseq.waddr   = `QUADSPI_DLR; 
	  wseq.wdata   = 32'h0000000F;    //16 bytes
	//wseq.wdata   = 32'h0000000b;  //12 bytes 
	//wseq.wdata   = 32'h0000001F;  //32 bytes 
	//wseq.wdata   = 32'h00000010; 
 
    wseq.start(env.axi_agnt.sequencer);	

	//sending data to QUADSPI_CCR
	wseq.waddr = `QUADSPI_CCR; 
	wseq.wdata = 32'h05003513; // Normal read operation 
	//wseq.wdata = 32'h05203513; // Normal read operation - 8 dummy cycles
	//wseq.wdata = 32'h05202568; // Normal read operation - 8 dummy cycles
 
    wseq.start(env.axi_agnt.sequencer);	
	     
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR;
	//wseq.wdata = 32'h01000000;  //  
	//wseq.wdata = 32'h01000000;  //  
	wseq.wdata   = 32'h00010000;
 
    wseq.start(env.axi_agnt.sequencer);			
    
    repeat(4) begin	
	#10000000;
    // Reading data from QUADSPI_DR
	rseq.raddr = `QUADSPI_DR;
    rseq.start(env.axi_agnt.sequencer);    
    end
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_ifc_rg_sr_tcf); 
	    		
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b;  
    wseq.start(env.axi_agnt.sequencer); */
    
    $display("Deep Power Down Mode command test case completed");
	
	       
    phase.drop_objection(this);
	
    //set a drain-time for the environment if desired
    phase.phase_done.set_drain_time(this, 100);
    
  endtask : run_phase

endclass : DeepPowerDownMode
